home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xskewb / xskewb.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  12KB  |  414 lines

  1. /*
  2. # X-BASED SKEWB
  3. #
  4. #  xskewb.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 4: 94/05/30 Xt
  28.   Version 3: 93/10/14 Motif
  29.   Version 2: 92/01/22 XView
  30.   Version 1: 91/03/19 SunView
  31. */
  32.  
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #ifdef VMS
  36. #include <unixlib.h>
  37. #define getlogin cuserid
  38. #else
  39. #ifndef apollo
  40. #include <unistd.h>
  41. #endif
  42. #endif
  43. #include <X11/Intrinsic.h>
  44. #include <X11/StringDefs.h>
  45. #include <X11/Shell.h>
  46. #include <X11/cursorfont.h>
  47. #include "Skewb.h"
  48. #include "Skewb2d.h"
  49. #include "Skewb3d.h"
  50. #include "skewb.xbm"
  51.  
  52. #ifndef SCOREFILE
  53. #define SCOREFILE "/usr/games/lib/skewb.scores"
  54. #endif
  55.  
  56. /* The following is in SkewbP.h also */
  57. #define MAXFACES 6
  58.  
  59. #define MAXRECORD 32767
  60. #define MAXPROGNAME 80
  61. #define MAXNAME 256
  62.  
  63. static void Initialize();
  64. static void CallbackSkewb();
  65.  
  66. static void PrintRecord();
  67. static int HandleSolved();
  68. static void PrintState();
  69. static void ReadRecords();
  70. static void WriteRecords();
  71.  
  72. static Widget skewb2d, skewb3d;
  73. static Arg arg[4];
  74. static int skewbRecord[2], movesDsp = 0;
  75. static char progDsp[64] = "xskewb";
  76. static char recordDsp[16] = "INF";
  77. static char messageDsp[128] = "Welcome";
  78. static char titleDsp[256] = "";
  79.  
  80. static void Usage()
  81. {
  82.   (void) fprintf(stderr, "usage: xskewb\n");
  83.   (void) fprintf(stderr, 
  84.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  85.   (void) fprintf(stderr, 
  86.     "\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
  87.   (void) fprintf(stderr,
  88.     "\t[-{border|bd} {color}] [-mono] [-[no]orient]\n");
  89.   (void) fprintf(stderr,
  90.     "\t[-[no]practice] [-face{0|1|2|3|4|5} {color}]\n");
  91.   exit(1);
  92. }
  93.  
  94. static XrmOptionDescRec options[] = {
  95.   {"-fg",        "*skewb.Foreground",    XrmoptionSepArg,    NULL},
  96.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  97.   {"-foreground",    "*skewb.Foreground",    XrmoptionSepArg,    NULL},
  98.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  99.   {"-border",        "*skewb.pieceBorder",    XrmoptionSepArg,    NULL},
  100.   {"-bd",        "*skewb.pieceBorder",    XrmoptionSepArg,    NULL},
  101.   {"-mono",        "*skewb.mono",        XrmoptionNoArg,        "TRUE"},
  102.   {"-orient",        "*skewb.orient",    XrmoptionNoArg,        "TRUE"},
  103.   {"-noorient",        "*skewb.orient",    XrmoptionNoArg,        "FALSE"},
  104.   {"-practice",        "*skewb.practice",    XrmoptionNoArg,        "TRUE"},
  105.   {"-nopractice",    "*skewb.practice",    XrmoptionNoArg,        "FALSE"},
  106.   {"-face0",        "*skewb.faceColor0",    XrmoptionSepArg,    NULL},
  107.   {"-face1",        "*skewb.faceColor1",    XrmoptionSepArg,    NULL},
  108.   {"-face2",        "*skewb.faceColor2",    XrmoptionSepArg,    NULL},
  109.   {"-face3",        "*skewb.faceColor3",    XrmoptionSepArg,    NULL},
  110.   {"-face4",        "*skewb.faceColor4",    XrmoptionSepArg,    NULL},
  111.   {"-face5",        "*skewb.faceColor5",    XrmoptionSepArg,    NULL},
  112. };
  113.  
  114. int main(argc, argv)
  115.   int argc;
  116.   char *argv[];
  117. {
  118.   Widget toplevel, shell;
  119.  
  120.   toplevel = XtInitialize(argv[0], "Skewb",
  121.     options, XtNumber(options), &argc, argv);
  122.   if (argc != 1)
  123.     Usage();
  124.  
  125.   shell = XtCreateApplicationShell(argv[0], topLevelShellWidgetClass, NULL,
  126.     0);
  127.   XtSetArg(arg[0], XtNiconPixmap,
  128.     XCreateBitmapFromData(XtDisplay(toplevel),
  129.       RootWindowOfScreen(XtScreen(toplevel)),
  130.       (char *) skewb_bits, skewb_width, skewb_height));
  131.   XtSetValues(toplevel, arg, 1);
  132.   XtSetArg(arg[0], XtNiconPixmap, 
  133.     XCreateBitmapFromData(XtDisplay(shell),
  134.       RootWindowOfScreen(XtScreen(shell)),
  135.       (char *) skewb_bits, skewb_width, skewb_height));
  136.   XtSetValues(shell, arg, 1);
  137.   skewb2d = XtCreateManagedWidget("skewb", skewb2dWidgetClass, toplevel,
  138.     NULL, 0);
  139.   XtAddCallback(skewb2d, XtNselectCallback, CallbackSkewb, NULL);
  140.   skewb3d = XtCreateManagedWidget("skewb", skewb3dWidgetClass, shell,
  141.     NULL, 0);
  142.   XtAddCallback(skewb3d, XtNselectCallback, CallbackSkewb, NULL);
  143.   Initialize();
  144.   XtRealizeWidget(toplevel);
  145.   XtRealizeWidget(shell);
  146.   XGrabButton(XtDisplay(skewb2d), AnyButton, AnyModifier, XtWindow(skewb2d),
  147.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  148.     GrabModeAsync, GrabModeAsync, XtWindow(skewb2d),
  149.     XCreateFontCursor(XtDisplay(skewb2d), XC_crosshair));
  150.   XGrabButton(XtDisplay(skewb3d), AnyButton, AnyModifier, XtWindow(skewb3d),
  151.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  152.     GrabModeAsync, GrabModeAsync, XtWindow(skewb3d),
  153.     XCreateFontCursor(XtDisplay(skewb3d), XC_crosshair));
  154.   XtMainLoop();
  155.  
  156. #ifdef VMS
  157.   return 1;
  158. #else
  159.   return 0;
  160. #endif
  161. }
  162.  
  163. /* There's probably a better way to assure that they are the same but
  164.    I don't know it off hand. */
  165. static void MakeEquivalent(orient, practice)
  166.   Boolean *orient, *practice;
  167. {
  168.   Boolean mono;
  169.   Pixel foreground, background, pieceBorder;
  170.   String faceColor[MAXFACES];
  171.  
  172.   XtVaGetValues(skewb2d,
  173.     XtNorient, orient,
  174.     XtNpractice, practice,
  175.     XtNmono, &mono,
  176.     XtNforeground, &foreground,
  177.     XtNbackground, &background,
  178.     XtNpieceBorder, &pieceBorder,
  179.     XtNfaceColor0, &(faceColor[0]),
  180.     XtNfaceColor1, &(faceColor[1]),
  181.     XtNfaceColor2, &(faceColor[2]),
  182.     XtNfaceColor3, &(faceColor[3]),
  183.     XtNfaceColor4, &(faceColor[4]),
  184.     XtNfaceColor5, &(faceColor[5]),
  185.     NULL);
  186.   XtVaSetValues(skewb2d,
  187.     XtNdirection, SKEWB_IGNORE,
  188.     XtNstart, FALSE,
  189.     NULL);
  190.   XtVaSetValues(skewb3d,
  191.     XtNorient, *orient,
  192.     XtNpractice, *practice,
  193.     XtNmono, mono,
  194.     XtNdirection, SKEWB_IGNORE,
  195.     XtNstart, FALSE,
  196.     XtNforeground, foreground,
  197.     XtNbackground, background,
  198.     XtNpieceBorder, pieceBorder,
  199.     XtNfaceColor0, faceColor[0],
  200.     XtNfaceColor1, faceColor[1],
  201.     XtNfaceColor2, faceColor[2],
  202.     XtNfaceColor3, faceColor[3],
  203.     XtNfaceColor4, faceColor[4],
  204.     XtNfaceColor5, faceColor[5],
  205.     NULL);
  206. }
  207.  
  208. static void Initialize()
  209. {
  210.   Boolean orient, practice;
  211.  
  212.   MakeEquivalent(&orient, &practice);
  213.   ReadRecords();
  214.   PrintRecord(orient, practice, recordDsp);
  215.   PrintState(XtParent(skewb2d), progDsp, 2, movesDsp,
  216.     recordDsp, messageDsp);
  217.   PrintState(XtParent(skewb3d), progDsp, 3, movesDsp,
  218.     recordDsp, messageDsp);
  219. }
  220.  
  221. static void CallbackSkewb(w, clientData, callData)
  222.   Widget w;
  223.   caddr_t clientData;
  224.   skewbCallbackStruct *callData;
  225. {
  226.   int dim, otherdim;
  227.   Boolean orient, practice, start;
  228.   Widget otherw;
  229.  
  230.   if (w == skewb2d) {
  231.     dim = 2;
  232.     otherw = skewb3d;
  233.     otherdim = 3;
  234.   } else { /* (w == skewb3d) */
  235.     dim = 3;
  236.     otherw = skewb2d;
  237.     otherdim = 2;
  238.   }
  239.   XtVaGetValues(w,
  240.     XtNorient, &orient,
  241.     XtNpractice, &practice,
  242.     XtNstart, &start,
  243.     NULL);
  244.   (void) strcpy(messageDsp, "");
  245.   switch (callData->reason) {
  246.     case SKEWB_RESTORE:
  247.       XtSetArg(arg[0], XtNdirection, SKEWB_RESTORE);
  248.       XtSetValues(otherw, arg, 1);
  249.       XtSetValues(w, arg, 1);
  250.       movesDsp = 0;
  251.       break;
  252.     case SKEWB_RESET:
  253.       movesDsp = 0;
  254.       break;
  255.     case SKEWB_ILLEGAL:
  256.       if (practice || start)
  257.         (void) strcpy(messageDsp, "Illegal move");
  258.       else
  259.         (void) strcpy(messageDsp, "Randomize to start");
  260.       break;
  261.     case SKEWB_MOVED:
  262.       movesDsp++;
  263. #ifdef DEBUG
  264.       if (movesDsp > 256)
  265.         exit(1);
  266. #endif
  267.       XtSetArg(arg[0], XtNstart, TRUE);
  268.       XtSetArg(arg[1], XtNface, callData->face);
  269.       XtSetArg(arg[2], XtNpos, callData->position);
  270.       XtSetArg(arg[3], XtNdirection, callData->direction);
  271.       XtSetValues(otherw, arg, 4);
  272.       XtSetValues(w, arg, 1);
  273.       break;
  274.     case SKEWB_CONTROL:
  275.       XtSetArg(arg[0], XtNface, callData->face);
  276.       XtSetArg(arg[1], XtNpos, callData->position);
  277.       XtSetArg(arg[2], XtNdirection, callData->direction);
  278.       XtSetValues(otherw, arg, 3);
  279.       return;
  280.     case SKEWB_SOLVED:
  281.       if (practice)
  282.         movesDsp = 0;
  283.       else { 
  284.         if (HandleSolved(movesDsp, orient))
  285.           (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  286.         else
  287.           (void) strcpy(messageDsp, "Solved!");
  288.       }
  289.       XtSetArg(arg[0], XtNstart, FALSE);
  290.       XtSetValues(w, arg, 1);
  291.       XtSetValues(otherw, arg, 1);
  292.       break;
  293.     case SKEWB_PRACTICE:
  294.       movesDsp = 0;
  295.       practice = !practice;
  296.       if (!practice)
  297.         (void) strcpy(messageDsp, "Randomize to start");
  298.       PrintRecord(orient, practice, recordDsp);
  299.       XtSetArg(arg[0], XtNpractice, practice);
  300.       XtSetArg(arg[1], XtNstart, FALSE);
  301.       XtSetValues(w, arg, 2);
  302.       XtSetValues(otherw, arg, 2);
  303.       break;
  304.     case SKEWB_RANDOMIZE:
  305.       movesDsp = 0;
  306.       XtSetArg(arg[0], XtNpractice, FALSE);
  307.       XtSetArg(arg[1], XtNstart, FALSE);
  308.       XtSetValues(w, arg, 2);
  309.       XtSetValues(otherw, arg, 2);
  310.       break; 
  311.     case SKEWB_ORIENT:
  312.       movesDsp = 0;
  313.       orient = !orient;
  314.       PrintRecord(orient, practice, recordDsp);
  315.       XtSetArg(arg[0], XtNorient, orient);
  316.       XtSetValues(w, arg, 1);
  317.       XtSetValues(otherw, arg, 1);
  318.       break;
  319.     case SKEWB_COMPUTED:
  320.       XtSetArg(arg[0], XtNstart, FALSE);
  321.       XtSetValues(w, arg, 1);
  322.       XtSetValues(otherw, arg, 1);
  323.       break;
  324.     case SKEWB_UNDO:
  325.       movesDsp--;
  326.       XtSetArg(arg[0], XtNstart, TRUE);
  327.       XtSetArg(arg[1], XtNface, callData->face);
  328.       XtSetArg(arg[2], XtNpos, callData->position);
  329.       XtSetArg(arg[3], XtNdirection, callData->direction);
  330.       XtSetValues(otherw, arg, 4);
  331.       XtSetValues(w, arg, 1);
  332.       break;
  333.   }
  334.   PrintState(XtParent(w), progDsp, dim, movesDsp,
  335.     recordDsp, messageDsp);
  336.   PrintState(XtParent(otherw), progDsp, otherdim, movesDsp,
  337.     recordDsp, messageDsp);
  338. }
  339.  
  340. static void PrintRecord(orient, practice, record)
  341.   Boolean orient, practice;
  342.   char *record;
  343. {
  344.   int i = (orient) ? 1 : 0;
  345.  
  346.   if (practice)
  347.     (void) strcpy(record, "practice");
  348.   else if (skewbRecord[i] >= MAXRECORD)
  349.     (void) strcpy(record, "NEVER");
  350.   else
  351.     (void) sprintf(record, "%d", skewbRecord[i]);
  352. }
  353.  
  354. static int HandleSolved(counter, orient)
  355.   int counter;
  356.   Boolean orient;
  357. {
  358.   int i = (orient) ? 1 : 0;
  359.  
  360.   if (counter < skewbRecord[i]) {
  361.     skewbRecord[i] = counter;
  362.     if (orient && (skewbRecord[i] < skewbRecord[!i]))
  363.       skewbRecord[!i] = counter;
  364.     WriteRecords();
  365.     (void) sprintf(recordDsp, "%d", counter);
  366.     return TRUE;
  367.   }
  368.   return FALSE;
  369. }
  370.  
  371. static void PrintState(w, prog, dim, moves, record, message)
  372.   Widget w;
  373.   char *prog, *record, *message;
  374.   int dim, moves;
  375. {
  376.   (void) sprintf(titleDsp, "%s%dd: (%d/%s) - %s", prog, dim, moves,
  377.     record, message);
  378.   XtSetArg(arg[0], XtNtitle, titleDsp);
  379.   XtSetValues(w, arg, 1);
  380. }
  381.  
  382. static void ReadRecords()
  383. {
  384.   FILE *fp;
  385.   int n, orient;
  386.  
  387.   for (orient = 0; orient < 2; orient++)
  388.     skewbRecord[orient] = MAXRECORD;
  389.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  390.     (void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
  391.   else {
  392.     for (orient = 0; orient < 2; orient++) {
  393.       (void) fscanf(fp, "%d", &n);
  394.       skewbRecord[orient] = n;
  395.     }
  396.     (void) fclose(fp);
  397.   }
  398. }
  399.  
  400. static void WriteRecords()
  401. {
  402.   FILE *fp;
  403.   int orient;
  404.  
  405.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  406.     (void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
  407.   else {
  408.     for (orient = 0; orient < 2; orient++)
  409.       (void) fprintf(fp, "%d ", skewbRecord[orient]);
  410.     (void) fprintf(fp, "\n");
  411.     (void) fclose(fp);
  412.   }
  413. }
  414.